﻿#pragma once

#include <cstdint>
#include <ostream>
#include <string>

namespace kratos {
namespace service {

struct EndLog {};

/**
 * 模块日志.
 * 
 * 支持日志等级:
 * VERBOSE     = 1; verbose
 * INFORMATION = 2; information
 * DIAGNOSE    = 3; debug for programmer
 * WARNING     = 4; something wrong but can recover
 * EXCEPTION   = 5; exception thrown
 * FAILURE     = 6; system failure
 * FATAL       = 7; fatal error cannot recover
 * 
 */
class ServiceLogger {
public:
  /**
   * 析构.
   *
   */
  virtual ~ServiceLogger() {}
  /**
   * 写入日志，等级VERBOSE.
   * 
   * \param log 日志
   * \return 
   */
  virtual auto verbose_log(const std::string &log) -> void = 0;
  /**
   * 写入日志，等级INFORMATION.
   *
   * \param log 日志
   * \return
   */
  virtual auto info_log(const std::string &log) -> void = 0;
  /**
   * 写入日志，等级DIAGNOSE.
   *
   * \param log 日志
   * \return
   */
  virtual auto debug_log(const std::string &log) -> void = 0;
  /**
   * 写入日志，等级WARNING.
   *
   * \param log 日志
   * \return
   */
  virtual auto warn_log(const std::string &log) -> void = 0;
  /**
   * 写入日志，等级EXCEPTION.
   *
   * \param log 日志
   * \return
   */
  virtual auto except_log(const std::string &log) -> void = 0;
  /**
   * 写入日志，等级FAILURE.
   *
   * \param log 日志
   * \return
   */
  virtual auto fail_log(const std::string &log) -> void = 0;
  /**
   * 写入日志，等级FAILURE.
   *
   * \param log 日志
   * \return
   */
  virtual auto fatal_log(const std::string &log) -> void = 0;
  /**
   * 流式日志起始
   * 使用：log->verbose() << "abc" << "efg" << EndLog;
   * 
   * \return ServiceLogger
   */
  virtual auto verbose() -> ServiceLogger & = 0;
  /**
   * 流式日志起始
   * 使用：log->info() << "abc" << "efg" << EndLog;
   *
   * \return ServiceLogger
   */
  virtual auto info() -> ServiceLogger & = 0;
  /**
   * 流式日志起始
   * 使用：log->debug() << "abc" << "efg" << EndLog;
   *
   * \return ServiceLogger
   */
  virtual auto debug() -> ServiceLogger & = 0;
  /**
   * 流式日志起始
   * 使用：log->warn() << "abc" << "efg" << EndLog;
   *
   * \return ServiceLogger
   */
  virtual auto warn() -> ServiceLogger & = 0;
  /**
   * 流式日志起始
   * 使用：log->except() << "abc" << "efg" << EndLog;
   *
   * \return ServiceLogger
   */
  virtual auto except() -> ServiceLogger & = 0;
  /**
   * 流式日志起始
   * 使用：log->fail() << "abc" << "efg" << EndLog;
   *
   * \return ServiceLogger
   */
  virtual auto fail() -> ServiceLogger & = 0;
  /**
   * 流式日志起始
   * 使用：log->fatal() << "abc" << "efg" << EndLog;
   *
   * \return ServiceLogger
   */
  virtual auto fatal() -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   * 
   * \return ServiceLogger
   */
  virtual auto operator<<(const char *str) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(const std::string &str) -> ServiceLogger & = 0;
  /**
   * 流式日志写入, 右值
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::string &&str) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::int8_t i8) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::uint8_t ui8) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::int16_t i16) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::uint16_t ui16) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::int32_t i32) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::uint32_t ui32) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::int64_t i64) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(std::uint64_t ui64) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(float f) -> ServiceLogger & = 0;
  /**
   * 流式日志写入.
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(double d) -> ServiceLogger & = 0;
  /**
   * 流式日志写入结束
   *
   * \return ServiceLogger
   */
  virtual auto operator<<(const EndLog &) -> ServiceLogger & = 0;
};

} // namespace service
} // namespace kratos
